home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
clean
/
sun3.lha
/
Sun3
/
seqdemos
/
lqueen.icl
< prev
next >
Wrap
Text File
|
1992-08-07
|
2KB
|
79 lines
MODULE lqueen;
<<
The Queens Problem.
Or: How to put n queens on a n*n chessboard in such a way that they
cannot attack each other.
The result of this program is the number of possible solutions for
the queens problem for a certain boardsize together with one solution.
When BoardSize is 8 the result will be: (92,[4,2,7,3,6,8,5,1]),
which means the queens are on a4, b2, c7, d3, e6, f8, g5 and h1.
This program is the fastest possible algorithm (?) for the Queens problem
in Clean without strictness annotations added by the programmer. It runs
about 40% slower than the fastest possible algorithm (?) with strictness
annotations added by the programmer (squeen.icl).
>>
IMPORT deltaI, deltaB;
MACRO
BoardSize -> 8; == The size of the chessboard.
RULE
== Miscellaneous list functions.
:: Length [x] -> INT;
Length [hd|tl] -> ++ (Length tl);
Length [] -> 0;
:: Head [x] -> x;
Head [hd|tl] -> hd;
== Finding all solutions for the queens problem.
:: Queens INT [INT] [[INT]] -> [[INT]];
Queens row board boards -> [board | boards] , IF > row BoardSize
-> TryCols BoardSize row board boards;
<< The second alternative of TryCols is added to make sure Save is never
called with an empty list.
>>
:: TryCols INT INT [INT] [[INT]] -> [[INT]];
TryCols 0 row board boards
-> boards;
TryCols col row [] boards
-> TryCols (-- col) row [] queens,
queens: Queens (++ row) [col] boards;
TryCols col row board boards
-> TryCols (-- col) row board queens , IF Save col 1 board
-> TryCols (-- col) row board boards,
queens: Queens (++ row) [col | board] boards;
<< Save will never be called with an empty list as third argument, so
no alternative for that case is needed, which means the strictness
analyser can now deduce strictness of the first and second argument
of Save.
>>
:: Save INT INT [INT] -> BOOL;
Save c1 rdiff [c2]
-> AND (<> cdiff 0) (AND (<> cdiff rdiff) (<> cdiff (- 0 rdiff))),
cdiff: - c1 c2;
Save c1 rdiff [c2|cols]
-> FALSE , IF = cdiff rdiff || = cdiff 0 || = cdiff (- 0 rdiff)
-> Save c1 (++ rdiff) cols,
cdiff: - c1 c2;
<< The Start Rule: Calculate the list of solutions, show the first
solution and the length of that list.
>>
:: Start -> (INT,[INT]);
Start -> (Length solutions, Head solutions),
solutions: Queens 1 [] [];